///<reference path='SPRESTListItem.ts'/>
///<reference path='SPRESTFolder.ts' />
///<reference path='SPRESTListItemCollection.ts' />
///<reference path='SPRESTContentTypeCollection.ts' />

// Module
module SPREST {

    // Interface
    export interface QueryCriteria {
        field: string;
        value: any;
        operator: string; // eq, neq, gt, lt, gte, lte
    }

    // Class
    export class List {
        public urlFirstUniqueAncestorSecurableObject: string = null;
        public urlRoleAssignments: string = null;
        public urlContentTypes: string = null;
        public urlDefaultView: string = null;
        public urlEventReceivers: string = null;
        public urlFields: string = null;
        public urlForms: string = null;
        public urlInformationRightsManagementSettings: string = null;
        public urlItems: string = null;
        public urlParentWeb: string = null;
        public urlRootFolder: string = null;
        public urlUserCustomActions: string = null;
        public urlViews: string = null;
        public urlWorkflowAssociations: string = null;
        public allowContentTypes: bool = null;
        public baseTemplate: number = null;
        public baseType: number = null;
        public contentTypesEnabled: bool = null;
        public created: string = null;
        public defaultContentApprovalWorkflowId: string = null;
        public description: string = null;
        public direction: string = null;
        public documentTemplateUrl: string = null;
        public draftVersionVisibility: number = null;
        public enableAttachments: bool = false;
        public enableFolderCreation: bool = null;
        public enableMinorVersions: bool = null;
        public enableModeration: bool = null;
        public enableVersioning: bool = null;
        public entityTypeName: string = null;
        public forceCheckout: bool = null;
        public hasExternalDataSource: bool = null;
        public hidden: bool = null;
        public id: string = null;
        public imageUrl: string = null;
        public irmEnabled: bool = null;
        public irmExpire: bool = null;
        public irmReject: bool = null;
        public isApplicationList: bool = null;
        public isCatalog: bool = null;
        public isPrivate: bool = null;
        public itemCount: number = null;
        public lastItemDeletedDate: string = null;
        public lastItemModifiedDate: string = null;
        public listItemEntityTypeFullName: string = null;
        public multipleDataList: bool = null;
        public noCrawl: bool = null;
        public parentWebUrl: string = null;
        public serverTemplateCanCreateFolders: bool = null;
        public templateFeatureId: string = null;
        public title: string = null;

        // Constructor
        constructor (public Context:SPREST.Context, public Web: SPREST.Web, listData) {
            this.urlFirstUniqueAncestorSecurableObject = listData.FirstUniqueAncestorSecurableObject.__deferred.uri;
            this.urlRoleAssignments = listData.RoleAssignments.__deferred.uri;
            this.urlContentTypes = listData.ContentTypes.__deferred.uri;
            this.urlDefaultView = listData.ContentTypes.__deferred.uri;
            this.urlEventReceivers = listData.EventReceivers.__deferred.uri;
            this.urlFields = listData.Fields.__deferred.uri;
            this.urlForms = listData.Forms.__deferred.uri;
            this.urlInformationRightsManagementSettings = listData.InformationRightsManagementSettings.__deferred.uri;
            this.urlItems = listData.Items.__deferred.uri;
            this.urlParentWeb = listData.ParentWeb.__deferred.uri;
            this.urlRootFolder = listData.RootFolder.__deferred.uri;
            this.urlUserCustomActions = listData.UserCustomActions.__deferred.uri;
            this.urlViews = listData.Views.__deferred.uri;
            this.urlWorkflowAssociations = listData.WorkflowAssociations.__deferred.uri;
            this.allowContentTypes = listData.AllowContentTypes;
            this.baseTemplate = listData.BaseTemplate;
            this.baseType = listData.BaseType;
            this.contentTypesEnabled = listData.ContentTypesEnabled;
            this.created = listData.Created;
            this.defaultContentApprovalWorkflowId = listData.DefaultContentApprovalWorkflowId;
            this.description = listData.Description;
            this.direction = listData.Direction;
            this.documentTemplateUrl = listData.DocumentTemplateUrl;
            this.draftVersionVisibility = listData.DraftVersionVisibility;
            this.enableAttachments = listData.EnableAttachments;
            this.enableFolderCreation = listData.EnableFolderCreation;
            this.enableMinorVersions = listData.EnabledMinorVersions;
            this.enableModeration = listData.EnableModeration;
            this.enableVersioning = listData.EnableVersioning;
            this.entityTypeName = listData.EntityTypeName;
            this.forceCheckout = listData.ForceCheckout;
            this.hasExternalDataSource = listData.HasExternalDataSource;
            this.hidden = listData.Hidden;
            this.id = listData.Id;
            this.imageUrl = listData.ImageUrl;
            this.irmEnabled = listData.IrmEnabled;
            this.irmExpire = listData.IrmExpire;
            this.irmReject = listData.IrmReject;
            this.isApplicationList = listData.IsApplicationList;
            this.isCatalog = listData.IsCatalog;
            this.isPrivate = listData.IsPrivate;
            this.itemCount = listData.ItemCount;
            this.lastItemDeletedDate = listData.LastItemDeletedDate;
            this.lastItemModifiedDate = listData.LastItemModifiedDate;
            this.listItemEntityTypeFullName = listData.ListItemEntityTypeFullName;
            this.multipleDataList = listData.MultipleDataList;
            this.noCrawl = listData.NoCrawl;
            this.parentWebUrl = listData.ParentWebUrl;
            this.serverTemplateCanCreateFolders = listData.ServerTemplateCanCreateFolders;
            this.templateFeatureId = listData.TemplateFeatureId;
            this.title = listData.Title;
        }

        public rootFolderProperty: SPREST.Folder;

        RootFolder(): SPREST.Folder {
            if (this.rootFolderProperty != null) return this.rootFolderProperty;
            var folder = new SPREST.Folder(this.Context, this.Web, this.urlRootFolder);
            this.rootFolderProperty = folder;
            var dfd:JQueryDeferred = folder.start();
            return folder;
        }



        GetAllItems(): SPREST.ListItemCollection {
            var items: SPREST.ListItemCollection = new SPREST.ListItemCollection(this.Context, this, this.urlItems);
            items.start();
            return items;
        }

        GetItemsByQuery(queryParameters: SPREST.QueryCriteria[]): SPREST.ListItemCollection { 
            var listUrl = this.urlItems + '?' + this.GetFullFilterString(queryParameters);
            var items: SPREST.ListItemCollection = new SPREST.ListItemCollection(this.Context, this, listUrl);
            items.start();
            return items;
        }

        GetFullFilterString(criteria: SPREST.QueryCriteria[]): string {
            var result = '$filter=';
            for (var looper = 0; looper < criteria.length; looper++) {
                result += this.GetFilterString(criteria[looper]);
                if (looper + 1 < criteria.length) result += ' and ';
            }
            return result;
        }

        GetFilterString(criteria: SPREST.QueryCriteria) {
            var result = criteria.field + " " + criteria.operator.toLowerCase() + " '" + encodeURIComponent(criteria.value) + "'";
            return result;
        }

        AddItem(item: any):JQueryDeferred {
            var dfd: JQueryDeferred = $.Deferred();
            var myThis = this;
            var myItem = { "__metadata": { 'type': myThis.listItemEntityTypeFullName } };
            for (var prop in item) {
                myItem[prop] = item[prop];
            }
            var ajaxSettings: JQueryAjaxSettings = {
                async: true,
                contentType: "application/json;odata=verbose",
                headers: { "Accept": "application/json;odata=verbose", "X-RequestDigest":myThis.Context.RequestDigest },
                type: "POST",
                data: JSON.stringify(myItem)
            };

            $.ajax(myThis.urlItems, ajaxSettings).fail(function(req, status, error) {
                dfd.reject(myThis, req, status, error);
            }).done(function (data) {
                var newItem: SPREST.ListItem = new SPREST.ListItem(myThis, null, data.d);
                dfd.resolve(newItem);
            });
            return dfd;
        }

        public contentTypeProp: SPREST.ContentTypeCollection = null;
        GetContentTypes(): SPREST.ContentTypeCollection {
            if (this.contentTypeProp != null) return this.contentTypeProp;
            var ctColl: SPREST.ContentTypeCollection = new SPREST.ContentTypeCollection(this.Context, this.Web, this.urlContentTypes);
            var dfd:JQueryDeferred = ctColl.start();
            return ctColl;
        }
    }

}

